package com.yungu.swift.api.route.v2.passenger;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.api.base.BaseApi;
import com.yungu.swift.api.facade.PassengerFacade;
import com.yungu.swift.assets.driver.model.dto.CarModelDto;
import com.yungu.swift.assets.driver.model.param.CarModelSiteParam;
import com.yungu.swift.assets.driver.service.CarModelService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.order.model.param.*;
import com.yungu.swift.order.model.vo.CrosstownHomeOrderInfoVo;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.order.service.OrderJoinService;
import com.yungu.swift.system.sys.model.dto.SysPointSiteDto;
import com.yungu.swift.system.sys.model.dto.SysWayDto;
import com.yungu.swift.system.sys.model.param.ApiPointMatchParam;
import com.yungu.swift.system.sys.model.param.ApiPointSiteParam;
import com.yungu.swift.system.sys.model.param.SysWayRelateParam;
import com.yungu.swift.system.sys.model.vo.SysWayInfoVo;
import com.yungu.swift.system.sys.service.SysWayService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.ParamUtil;
import com.yungu.swift.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.yungu.swift.api.base.ApiErrorEnum.PARAM_ERROR;

/**
 * 乘客端拼车订单接口
 */
@RestController
@RequestMapping(value = "/api/v2/passenger", method = {RequestMethod.POST, RequestMethod.GET})
@Api(value = "【乘客】【订单】【跨城拼车】跨车拼车订单接口V2", tags = "V2-跨车拼车订单接口")
public class PasOrderJoinApi extends BaseApi {

    @Autowired
    private PassengerFacade passengerFacade;

    @Reference
    private SysWayService sysWayService;
    @Reference
    private CarModelService carModelService;
    @Reference
    private OrderJoinService orderJoinService;
    @Reference
    private OrderFareService orderFareService;

    @PostMapping(value = {"/join/pointMatchedByAreaSiteCheck"})
    @ApiOperation(value = "校验某一坐标是否被某一区域类型起终点范围覆盖", notes = "是否匹配:isMatchOk（0否 1是）", httpMethod = "POST")
    public ResponseData<Map<String, Integer>> pointMatchedByAreaSiteCheck(@RequestHeader String appid,
                                                                          @Valid @RequestBody ApiPointMatchParam pointMatchParam) {
        return sysWayService.pointMatchedByAreaSiteCheck(pointMatchParam.getPasLng(), pointMatchParam.getPasLat(),
                pointMatchParam.getTargetSiteUuid(), pointMatchParam.getOriginSiteUuid());
    }

    @PostMapping(value = {"/join/waysOriginByPas"})
    @ApiOperation(value = "获取已开通城市及线路起点接口（针对乘客）")
    public ResponseData<List<SysPointSiteDto>> waysOriginByPas(@RequestHeader String appid,
                                                               @RequestBody ApiPointSiteParam pointSiteParam) {
        return sysWayService.waysOriginByPoint(appid, pointSiteParam.getPasLng(), pointSiteParam.getPasLat(),
                pointSiteParam.getOnlyMatch(), pointSiteParam.getBusinessType(), pointSiteParam.getOrderDemand(),
                pointSiteParam.getTransferType());
    }

    @PostMapping(value = {"/join/waysDestByPas"})
    @ApiOperation(value = "根据起点获取匹配线路终点接口")
    public ResponseData<List<SysPointSiteDto>> waysDestByPas(@RequestHeader String appid,
                                                             @RequestBody ApiPointSiteParam pointSiteParam) {
        if (StringUtils.isEmpty(pointSiteParam.getOriginUuid())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        return sysWayService.waysDestByOrigin(appid, pointSiteParam.getOriginUuid(), pointSiteParam.getOrderDemand());
    }

    @PostMapping(value = {"/join/maxPasSeats"})
    @ApiOperation(value = "获得可选最大座位数")
    public ResponseData<Map<String, Integer>> maxPasSeats(@RequestHeader String appid,
                                                          @RequestBody ApiPointSiteParam pointSiteParam) {
        if (ParamUtil.isIllegal(pointSiteParam.getOriginUuid(), pointSiteParam.getDestUuid())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        CarModelSiteParam modelSiteParam = new CarModelSiteParam();
        modelSiteParam.setBusinessType(CommonConstant.BUSINESS_TYPE_POOL);
        modelSiteParam.setOriginUuid(pointSiteParam.getOriginUuid());
        modelSiteParam.setDestUuid(pointSiteParam.getDestUuid());
        modelSiteParam.setAppid(appid);
        ResponseData<List<CarModelDto>> listCarModelByPointSite = carModelService.listCarModelByPointSite(modelSiteParam);
        if (listCarModelByPointSite.isSuccess() && CollectionUtils.isNotEmpty(listCarModelByPointSite.getData())) {
            //最大座位数
            Integer maxPassengerSeats = listCarModelByPointSite.getData().stream().mapToInt(CarModelDto::getMaxPassengerSeats).max().getAsInt();
            Map<String, Integer> resultMap = new HashMap<>(2);
            resultMap.put("maxPassengerSeats", maxPassengerSeats);
            return ResponseData.buildSuccessResponse(resultMap);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "可选最大座位数获取失败");
    }

    @PostMapping(value = {"/join/listCarLevel"})
    @ApiOperation(value = "获取车型列表接口")
    public ResponseData<List<Map<String, Object>>> listCarLevel(@RequestHeader String appid,
                                                                @Valid @RequestBody ApiJoinCarModelParam joinCarModelParam) {
        joinCarModelParam.setAppid(appid);
        return orderFareService.crosstownCarLevelFareList(joinCarModelParam);
    }

    @PostMapping(value = {"/token/join/order/create"})
    @ApiOperation(value = "创建跨城拼车订单接口")
    public ResponseData<Map<String, Object>> createOrder(@Valid @RequestBody ApiJoinOrderParam apiJoinOrderParam) {
        JoinOrderParam joinOrderParam = new JoinOrderParam();
        BeanUtils.copyProperties(apiJoinOrderParam, joinOrderParam);
        joinOrderParam.setTypeModule(CommonConstant.BUSINESS_TYPE_POOL);
        joinOrderParam.setOriginSiteUuid(apiJoinOrderParam.getOriginUuid());
        joinOrderParam.setDestSiteUuid(apiJoinOrderParam.getDestUuid());
        return passengerFacade.createJoinOrder(joinOrderParam);
    }

    @PostMapping(value = {"/token/join/home/order"})
    @ApiOperation(value = "首页拼车订单接口")
    public ResponseData<List<CrosstownHomeOrderInfoVo>> homeOrder(@RequestBody ApiJoinListParam demandParam) {
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("passengerUuid", demandParam.getUserUuid());
        paraMap.put("orderDemand", demandParam.getOrderDemand());
        paraMap.put("typeModule", demandParam.getTypeModule());
        return orderJoinService.getCrosstownHomeOrderInfo(paraMap);
    }


    @PostMapping(value = {"/token/join/order/cancel"})
    @ApiOperation(value = "取消订单 —— 已生效")
    public ResponseData<Boolean> cancelOrder(@RequestBody JoinOrderParam joinOrderParam) {
        if (ParamUtil.isIllegal(joinOrderParam.getOrderUuid())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        joinOrderParam.setCloseType(ParamUtil.defaultIfNull(joinOrderParam.getCloseType(), "PAS_CANCEL"));
        return orderJoinService.closeJoinOrder(joinOrderParam);
    }

    @PostMapping(value = {"/join/way/info"})
    @ApiOperation(value = "路线的取消费用/取消规则 —— 已生效")
    public ResponseData<Map<String, Object>> wayInfo(@RequestBody ApiJoinCancelParam cancelParam) {
        if (ParamUtil.isIllegal(cancelParam.getWayUuid())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        Map<String, Object> resultMap = new HashMap<>();
        //跨城小件时  取消规则与拼车有差异 需要支付一定取消费 查询线路 并根据订单状态判断取消费
        if (cancelParam.getTypeModule() != null && CommonConstant.BUSINESS_TYPE_PARCEL == cancelParam.getTypeModule()) {
            Double actualFare = Optional.ofNullable(cancelParam.getActualFare()).orElse(0.0);
            SysWayRelateParam sysWayRelateParam = new SysWayRelateParam();
            sysWayRelateParam.setSystemWayUuid(cancelParam.getWayUuid());
            ResponseData<SysWayInfoVo> responseData = sysWayService.getParcelRule(cancelParam.getWayUuid());
            if (responseData.isSuccess() && responseData.getData() != null) {
                SysWayInfoVo sysWayInfoVo = responseData.getData();
                //小件取消费 当前规则 已派司机的小件订单取消时需要支付取消费 已出发订单将全额扣款
                Double parcelCancelFee = Optional.ofNullable(sysWayInfoVo.getParcelCancelFee()).orElse(0.0);
                resultMap.put("cancelRule", sysWayInfoVo.getParcelCancelRule());
                if (cancelParam.getJoinStatus() != null && OrderConstant.ORDER_JOIN_STATUS_WAIT_START == cancelParam.getJoinStatus()) {
                    resultMap.put("cancelFee", parcelCancelFee > actualFare ? actualFare : parcelCancelFee);
                }
                if (cancelParam.getJoinStatus() != null && OrderConstant.ORDER_JOIN_STATUS_STARTED == cancelParam.getJoinStatus()) {
                    resultMap.put("cancelFee", actualFare);
                }
            }
        }
        if (cancelParam.getTypeModule() == null) {
            ResponseData<List<SysWayDto>> responseData = sysWayService.findWithOriginDest(MapUtils.build("wayUuid", cancelParam.getWayUuid()));
            if (responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())) {
                resultMap.put("cancelRule", responseData.getData().get(0).getCancelRule());
            }
        }
        return ResponseData.buildSuccessResponse("获取线路信息成功", resultMap);
    }

    @PostMapping(value = {"/join/way/infoBySite"})
    @ApiOperation(value = "通过起终点UUID获取路线信息 —— 已生效")
    public ResponseData<SysWayDto> wayInfoBySite(@RequestBody ApiPointSiteParam pointSiteParam) {
        if (ParamUtil.isIllegal(pointSiteParam.getOriginUuid(), pointSiteParam.getDestUuid())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        Map<String, Object> build = MapUtils.build(4);
        build.put("originSiteUuid", pointSiteParam.getOriginUuid());
        build.put("destSiteUuid", pointSiteParam.getDestUuid());
        ResponseData<List<SysWayDto>> responseData = sysWayService.findWithOriginDest(build);
        if (responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())) {
            return ResponseData.buildSuccessResponse(responseData.getData().get(0));
        }
        return ResponseData.buildErrorResponse(responseData.getErrCode(), responseData.getMsg());
    }


}
